/*
 * @Author: C.
 * @Date: 2025-04-15 16:26:12
 */
// 导入 Node.js 的 path 模块，用于处理和转换文件路径
import path from 'node:path';

// 导入 execa 库，用于在 Node.js 中执行外部命令
import { execa } from 'execa';

// 从 '@changesets/git' 模块导出所有内容
export * from '@changesets/git';

/**
 * 获取暂存区文件的绝对路径列表。
 * 该函数通过执行 `git` 命令来获取暂存区中被添加、复制、修改或重命名的文件列表，
 * 并将这些文件的相对路径转换为绝对路径。
 *
 * @returns 一个 Promise，解析为暂存区文件的绝对路径数组。如果执行命令失败，返回空数组。
 */
async function getStagedFiles(): Promise<string[]> {
  try {
    // 执行 git 命令，获取暂存区中被添加、复制、修改或重命名的文件列表
    // -c submodule.recurse=false: 禁止递归处理子模块
    // --staged: 仅显示暂存区的更改
    // --diff-filter=ACMR: 仅显示被添加、复制、修改或重命名的文件
    // --name-only: 仅显示文件名
    // --ignore-submodules: 忽略子模块的更改
    // -z: 使用 NUL 字符作为文件名的分隔符
    const { stdout } = await execa('git', [
      '-c',
      'submodule.recurse=false',
      'diff',
      '--staged',
      '--diff-filter=ACMR',
      '--name-only',
      '--ignore-submodules',
      '-z',
    ]);

    // 处理命令输出，去除末尾的 NUL 字符，并按 NUL 字符分割成数组
    let changedList = stdout ? stdout.replace(/\0$/, '').split('\0') : [];
    // 将每个文件的相对路径转换为绝对路径
    changedList = changedList.map((item) => path.resolve(process.cwd(), item));
    // 使用 Set 数据结构去除重复项
    const changedSet = new Set(changedList);
    // 从 Set 中删除空字符串
    changedSet.delete('');
    // 将 Set 转换为数组并返回
    return [...changedSet];
  } catch (error) {
    // 捕获并在控制台输出获取暂存区文件时发生的错误
    console.error('Failed to get staged files:', error);
    // 若执行命令失败，返回空数组
    return [];
  }
}

// 导出 getStagedFiles 函数，供其他模块使用
export { getStagedFiles };
